home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1999 July
/
Macworld (1999-07).dmg
/
Shareware World
/
Info
/
For Developers
/
Mops 3.4.sea
/
Mops source
/
Toolbox classes
/
TextEdit
< prev
next >
Wrap
Text File
|
1998-07-15
|
10KB
|
441 lines
\ Oct95 JRF Added noClip to Activate: & Deactivate: per MRH suggestion
\ modified New: to enable outline highliting of inactive TE
\ 25May93 DBH Added lastchar: to commonize a routine.
\ added kludge to #lines: to fix a bug.
\ Completely reworked currentline: to fix a speed problem.
\ 15May93 DBH Added textaddr: method to improve readability and code reuse.
\ Use textaddr: self in getline: .
\ Deleted addrlinestart: method because it is never reused.
\ Added lineEnd: method, so we can move there easily.
\ Delte general class declaration.
\ 11May93 DBH fixed getLine: so null is returned if last char in TE is
\ a carriage return. Added getpoint: and idle: methods.
\ 3Sep96 mrh added values lineStart and lineEnd, set by a getLine: call
\ Jan 98 mrh fixed TE scrap stuff for PowerPC
PPC? [IF] syscall TESetScrapLength [THEN] \ not a call on 68k
need terecord
variable OFFSET \ used in GetScrap call
0 value LINESTART \ these are set when we call getLine: - useful sometimes
0 value LINEEND
\ some routines to handle the clipboard
: TODESK ( -- oserr )
ZeroScrap ?EXIT \ out if error
[ ppc? ] [if]
TEGetScrapLength \ length
[else]
global TEScrpLength w@
[then]
'type TEXT \ theType
TEScrapHandle @
PutScrap
;
: FROMDESK ( -- oserr )
TEScrapHandle
'type TEXT \ theType
offset
GetScrap
[ ppc? ] [if]
dup 0>= IF TESetScrapLength
0 \ no error
THEN
[else]
dup 0>= IF global TEScrpLength w! \ store scrap length
0 \ no error
THEN
[then]
;
: SELCUT
actW IF cut: [ actW ] THEN ;
: SELCOPY
actW IF copy: [ actW ] THEN ;
: SELPASTE
actW IF paste: [ actW ] THEN ;
: SELCLEAR
actW IF clear: [ actW ] THEN ;
:class RGBColor super{ object }
68k_record
{ uint red
uint green
uint blue
}
:m SETCOLOR: \ ( red green blue -- )
put: blue put: green put: red ;m
:m GETCOLOR: \ ( -- red green blue )
get: red get: green get: blue ;m
;class
\ Note an object of class RGBColor will start off black, unless we change it.
:class TextStyle super{ object }
public
68k_record
{ int tsFont
byte tsFace
int tsSize
RGBColor tsColor
}
:m classinit: 9 put: tsSize ;m
;class
TextStyle theStyle
\ syscall TENew
\ syscall TEStyleNew
\ syscall TextFont
\ syscall TextSize
\ syscall TESetStyle
handle textHandle
:CLASS TextEdit super{ object }
handle TEHandle
public
bool styles?
end_public
:m useStyles: set: styles? ;m \ get rid of it when I fix the bug!
:m new: { dest view -- }
9 TextSize \ need a smallish initial default value
dest
view
get: styles?
IF TEStyleNew
ELSE TENew
THEN put: TEHandle
2 1 \ 2 selects OutlineHilite feature
get: TEHandle \ 1 sets its flag
TEFeatureFlag
drop \ don't want the returned result
;m
:m handle: ( -- tehandle )
get: TEHandle ;m
:m ptr: ( -- teRecord )
ptr: TEHandle ;m
:m noWrap:
ptr: self noWrap: teRecord ;m
:m WrapIt:
ptr: self wrapIt: teRecord ;m
:m >font: ( font# -- )
put: ivar> tsFont in theStyle
1 ( font ) theStyle false get: TEHandle TESetStyle
;m
:m >fontSize: ( n -- )
put: ivar> tsSize in theStyle
4 ( size ) theStyle false get: TEHandle TESetStyle
;m
:m >color: ( red green blue -- )
setColor: ivar> tsColor in theStyle
8 ( color ) theStyle false get: TEHandle TESetStyle
;m
:m >style: ( n -- )
put: ivar> tsFace in theStyle
2 ( face ) theStyle false get: TEHandle TESetStyle
;m
:m SETVIEWRECT: { left top rt bot \ adr -- }
ptr: TEHandle -> adr \ ptr: TEHandle setview: teRecord ;m ?? \ 19May93 DBH
top adr 8 + w! left adr 10 + w!
bot adr 12 + w! rt adr 14 + w! ;m
:m LINEHEIGHT: ( -- n )
ptr: TEHandle lineHeight: teRecord ;m
\ :m #lines: ( -- n)
\ ptr: TEHandle #lines: teRecord \ note message to class
\ ;m
:m cut:
get: TEHandle TECut
todesk drop ;m \ not looking at error
:m copy:
get: TEHandle TECopy
todesk drop ;m \ not looking at error
:m paste:
fromdesk ?EXIT \ out if error
get: TEHandle TEPaste ;m
:m clear:
0 0 SetOrigin
get: TEHandle TEDelete ;m
:m update: \ ( rptr -- )
0 0 SetOrigin
get: TEHandle TEUpdate
;m
:m SCROLL: \ ( dx dy -- )
0 0 SetOrigin
get: TEHandle TEScroll ;m
:m size: ( -- len ) \ returns the length of the text
ptr: TEHandle size: teRecord ;m \ note message to class
:m TextHandle: \ ( -- hndl )
get: TEhandle TEGetText dup put: textHandle ;m
:m textaddr: \ ( -- addr ) \ addr of the first char of the TE text
textHandle: self @ ;m
:m get: ( -- $addr len )
textaddr: self
size: self ;m
:m getText&lock: ( -- hState addr len )
get: self \ I'll do this first, before locking the handle, since
\ I can't assume TE won't unlock it
getState: textHandle down
lock: textHandle ;m
:m >hState: ( hState -- )
textHandle: self drop
setState: textHandle
;m
:m put: ( $addr len -- )
get: TEHandle TESetText
update: self ;m
:m insert: ( addr len -- )
get: TEHandle TEInsert
;m
:m activate:
noClip
get: TEHandle TEActivate ;m
:m deactivate:
noClip
get: TEHandle TEDeactivate ;m
:m release:
get: TEHandle TEDispose
clear: TEHandle ;m
:m click:
where: fEvent g->l
mods: fevent $ 200 and 0<> negate \ extend if shift key (need a
\ Pascal-style boolean
handle: self TEClick
;m
:m select: ( start end -- ) \ hilites the given range
get: TEHandle TESetSelect ;m
:m selectAll: \ hilites all of the text
0 ( start)
size: self ( end)
select: self ;m
:m selStart: ( -- n )
ptr: TEHandle selStart: teRecord ;m
:m selEnd: ( -- n )
ptr: TEHandle selEnd: teRecord ;m
:m lastchar: ( -- char ) \ return last character in TE
textaddr: self size: self 1- + c@ ;m
:m key: { char \ bSel eSel -- }
\ TE for some reason doesn't handle forward delete, so we
\ have to special-case it.
char 127 =
IF \ yes, it's forward delete
selStart: self -> bSel
selEnd: self -> eSel
bSel eSel =
IF eSel size: self >= ?EXIT
eSel 1+ dup select: self
ELSE
eSel size: self <
IF bSel eSel 1+ select: self THEN
THEN
8 -> char
THEN
char get: TEHandle TEKey
;m
0 value kludge
:m #lines: ( -- n )
0 -> kludge
ptr: TEHandle #lines: class_as> teRecord
lastchar: self ret = IF -1 -> kludge 1+ THEN \ kludge Apple line numbering scheme!!
;m
\ given the zero-based line number, return the character# of the start of
\ that line
:m at: { n -- linestart }
n ( kludge + ) 1+ #lines: self > \ abort" TE linestart index out of range"
IF #lines: self 1- -> n THEN
ptr: TEHandle addrLineStart: class_as> teRecord
n 2* + w@
\ dup textaddr: self + c@ ret = IF 1+ THEN
;m
\ In the initial System 8, there's a bug in TEGetPoint - it expects a
\ spurious initial parameter! So for now I've kludged xcalls to say
\ it has 3 parms.
:m GETPOINT: { offset -- x y } \ given the char offset into the text, return the
\ corresponding x y location See IM V-269.
\ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
\ Apparently the call TEGetPoint has a bug in current PPC implementations
\ - the 2 parms are required to be in r4 and r5, instead of r3 and r4!
\ So we have to kludge this particular call to think it takes one more
\ cell than it really does. If Apple fixes the bug, we'll need to delete
\ this line. There's also 2 lines in zCallsMod.txt.
[ ppc? ] [if] 0 [then]
\ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
offset get: TEHandle TEGetPoint unpack ;m
:m currentLine: ( -- n )
selend: self getpoint: self ( x y ) nip ( cursor.y )
ptr: TEHandle ( dest) gettopy: rect - ( cursor.y - dest.top )
lineheight: self / 1-
selend: self size: self = \ true if at last char
size: self and \ and if not an empty size
IF
lastchar: self ret =
IF \ uh-oh, handle special case where last char is a ret
1+
THEN
THEN
;m
:m getLineN: { n -- addr len }
n at: self dup -> lineStart -> lineEnd
\ set lineStart and lineEnd to char offs of curr line start in case we EXIT
textaddr: self lineStart + \ addr of line start
#lines: self 1 - n =
IF \ we are on the last line
lastchar: self
ret =
IF \ we are on the last line AND just beyond a carriage return!
0 EXIT \ return zero len and get out
THEN
size: self
lineStart - ( len )
ELSE
linestart drop
n 1 + at: self
lineStart - 1 - ( len )
THEN
( len ) dup lineStart + -> lineEnd
;m
:m getLine: { \ n -- addr len } \ returns the line with the current selection.
size: self 0= IF textaddr: self 0 EXIT THEN \ out if no text
currentLine: self -> n
n getLineN: self
;m
:m LINEEND: { \ len pos -- pos } \ return the character position corresponding to the
\ end of the last line of the current selection.
selend: self size: self =
IF \ we are at the end of the text
size: self
ELSE
currentline: self at: self ( linestart ) -> pos
getline: self nip -> len
pos len +
THEN ;m
:m getselect: ( -- addr len ) \ returns hilited selection
ptr: TEHandle getselect: teRecord ;m
:m getSelect&lock: ( hState addr len -- )
getSelect: self \ I'll do this first, before locking the handle, since
\ I can't assume TE won't unlock it
textHandle: self drop
getState: textHandle down
lock: textHandle
;m
:m IDLE: \ May94 mh - Setting cursor now moved to TEScroller
get: TEHandle TEIdle
;m
:m DUMP:
selstart: self
selend: self
currentline: self
lineEnd: self
size: self { ss se cl le sz -- }
\ ss " selstart " >debug
\ se " selend " >debug
\ cl " currentline " >debug
\ le " lineEnd " >debug
\ sz " size " >debug
;m
;CLASS